"""
Agent基础抽象类
提供可扩展的Agent架构，支持不同类型的Agent继承和自定义
"""

import uuid
import json
import abc
import os
from typing import List, Dict, Any, Optional


class BaseAgent(abc.ABC):
    """Agent抽象基类，定义通用的Agent行为和接口"""
    
    def __init__(self, config_name: str = None):
        """
        初始化Agent
        
        Args:
            config_name: 配置文件名，不提供则使用类名自动推断
        """
        self.id = str(uuid.uuid4())
        self._load_config(config_name)
        self._init_components()
        self._post_init()
        
    def _load_config(self, config_name: str = None):
        """加载Agent配置"""
        try:
            # 延迟导入避免循环依赖
            from tools.utils import EnhancedOutput, OutputType
            
            # 如果没有提供配置名，使用类名推断
            if config_name is None:
                class_name = self.__class__.__name__.lower().replace('agent', '')
                config_name = class_name if class_name else 'ai'
            
            config_path = os.path.join("share/agents", f"agent_{config_name}.json")
            
            if not os.path.exists(config_path):
                raise FileNotFoundError(f"配置文件不存在: {config_path}")
            
            with open(config_path, "r", encoding="utf-8") as f:
                config_data = json.load(f)
            
            self.config = config_data["agent"]
            EnhancedOutput.display(f"成功加载配置: {config_path}", OutputType.SYSTEM)
            
        except Exception as e:
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(f"加载配置失败: {str(e)}", OutputType.ERROR)
            # 使用默认配置
            self.config = self._get_default_config()
    
    def _get_default_config(self) -> Dict[str, Any]:
        """获取默认配置，子类可以重写"""
        return {
            "name": "DefaultAgent",
            "version": "1.0",
            "description": "默认Agent配置",
            "system_prompt": "你是一个AI助手。",
            "mission": ["帮助用户解决问题"],
            "core_principles": ["诚实、可靠、有用"],
            "output_structure": {},
            "style_requirements": ["清晰、简洁"],
            "prohibited_actions": ["不生成有害内容"]
        }
    
    def _init_components(self):
        """初始化组件"""
        # 延迟导入避免循环依赖
        from models.modelmanager import ModelManager
        from memory.agentmemory import AgentMemory
        from tools.utils import EnhancedOutput
        
        # 从配置加载基本信息
        self.roleName = self.config.get("name", "AI助手")
        self.version = self.config.get("version", "1.0")
        self.description = self.config.get("description", "AI助手")
        self.mission = self.config.get("mission", [])
        self.core_principles = self.config.get("core_principles", [])
        self.output_structure = self.config.get("output_structure", {})
        self.style_requirements = self.config.get("style_requirements", [])
        self.prohibited_actions = self.config.get("prohibited_actions", [])
        
        # 初始化模型和记忆
        self.model = ModelManager.getGlobalPlatformModelManager().getModel("DeepSeek")
        self.memory = AgentMemory(self.id)
        self.memory.loadMemory()
        
        # 初始化工具注册器
        self.tools = self._create_tools_registry()
        
        # 构建系统提示
        self.system_prompt = self._build_system_prompt()
        
        # 初始化对话历史
        self.messages = [{"role": "system", "content": self.system_prompt}]
    
    def _create_tools_registry(self):
        """创建工具注册器，子类可以重写"""
        from tools.toolsregistry import ToolsRegistry
        return ToolsRegistry()
    
    def _build_system_prompt(self) -> str:
        """构建系统提示，子类可以重写"""
        prompt_parts = []
        
        # 基础系统提示
        if "system_prompt" in self.config:
            prompt_parts.append(self.config["system_prompt"])
        
        # 描述
        if self.description:
            prompt_parts.append(f"描述: {self.description}")
        
        # 使命
        if self.mission:
            prompt_parts.append(f"使命: {', '.join(self.mission)}")
        
        # 核心原则
        if self.core_principles:
            prompt_parts.append(f"核心原则: {', '.join(self.core_principles)}")
        
        # 输出结构
        if self.output_structure:
            prompt_parts.append(f"输出结构: {json.dumps(self.output_structure, ensure_ascii=False)}")
        
        # 风格要求
        if self.style_requirements:
            prompt_parts.append(f"风格要求: {', '.join(self.style_requirements)}")
        
        # 禁止行为
        if self.prohibited_actions:
            prompt_parts.append(f"禁止行为: {', '.join(self.prohibited_actions)}")
        
        # 工具提示
        tools_prompt = self.tools.toolsPrompt()
        if tools_prompt:
            prompt_parts.append(tools_prompt)
        
        return "\n\n".join(prompt_parts)
    
    def _post_init(self):
        """后初始化钩子，子类可以重写"""
        from tools.utils import EnhancedOutput, OutputType
        EnhancedOutput.display(f"{self.roleName} 初始化完成, 当前模型: {self.model.name()}", OutputType.SYSTEM)
    
    @property
    def name(self) -> str:
        """获取Agent名称"""
        return self.roleName
    
    def reset_conversation(self):
        """重置对话历史"""
        from tools.utils import EnhancedOutput, OutputType
        self.messages = [{"role": "system", "content": self.system_prompt}]
        EnhancedOutput.display(f"{self.name}: 对话历史已重置", OutputType.INFO)
    
    def get_recent_messages(self, num_messages: int = 10) -> List[str]:
        """获取最近的对话消息"""
        non_system_messages = [m for m in self.messages if m["role"] != "system"]
        if not non_system_messages:
            return []
        return [m["content"] for m in non_system_messages[-num_messages:]]
    
    def update_memory(self, user_input: str, response: str):
        """更新记忆，子类可以重写"""
        try:
            from tools.utils import EnhancedOutput, OutputType
            self.memory.addMemory(user_input, self.get_recent_messages(3), keywords=[])
        except Exception as e:
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(f"更新记忆失败: {str(e)}", OutputType.WARNING)
    
    @abc.abstractmethod
    def chat(self, user_input: str, reset: bool = False) -> str:
        """聊天接口，子类必须实现"""
        pass
    
    def handle_tool_calls(self, tool_calls: List[Dict]) -> str:
        """处理工具调用的通用逻辑"""
        if not tool_calls:
            return ""
        return self.tools.handleToolCalls(tool_calls)
    
    def parse_tool_calls(self, text: str) -> List[Dict]:
        """解析工具调用的通用逻辑"""
        return self.tools.parseToolCalls(text)


class ConversationalAgent(BaseAgent):
    """对话型Agent，处理一般对话任务"""
    
    def __init__(self, config_name: str = "ai"):
        super().__init__(config_name)
    
    def chat(self, user_input: str, reset: bool = False) -> str:
        """处理对话聊天"""
        if reset:
            self.reset_conversation()
        
        self.messages.append({"role": "user", "content": user_input})
        
        try:
            full_response = ""
            for chunk in self.model.chat(self.messages):
                full_response += chunk
            
            # 检查工具调用
            tool_calls = self.parse_tool_calls(full_response)
            
            if tool_calls:
                # 执行工具调用
                tool_result = self.handle_tool_calls(tool_calls)
                
                # 将工具执行结果添加到对话中
                self.messages.append({"role": "assistant", "content": full_response})
                self.messages.append({"role": "user", "content": f"工具执行结果:\n{tool_result}"})
                
                # 获取最终响应
                final_response = ""
                for chunk in self.model.chat(self.messages):
                    final_response += chunk
                
                self.messages.append({"role": "assistant", "content": final_response})
                self.update_memory(user_input, final_response)
                return final_response
            else:
                # 没有工具调用，直接返回响应
                self.messages.append({"role": "assistant", "content": full_response})
                self.update_memory(user_input, full_response)
                return full_response
                
        except Exception as e:
            from tools.utils import EnhancedOutput, OutputType
            error_msg = f"{self.name} 对话出错: {str(e)}"
            EnhancedOutput.display(error_msg, OutputType.ERROR)
            return error_msg


class TaskOrientedAgent(BaseAgent):
    """任务导向型Agent，专门处理特定任务"""
    
    def __init__(self, config_name: str, task_context: Dict[str, Any] = None):
        self.task_context = task_context or {}
        super().__init__(config_name)
    
    def _create_tools_registry(self):
        """任务导向型Agent可能需要专门的工具"""
        return self._get_specialized_tools()
    
    def _get_specialized_tools(self):
        """获取专门工具，子类需要重写"""
        from tools.toolsregistry import ToolsRegistry
        return ToolsRegistry()
    
    def set_task_context(self, context: Dict[str, Any]):
        """设置任务上下文"""
        self.task_context.update(context)
    
    def update_memory(self, user_input: str, response: str):
        """任务导向型Agent的记忆更新"""
        try:
            # 根据任务类型提取关键词
            task_keywords = self._extract_task_keywords()
            if task_keywords:
                self.memory.addMemory(user_input, self.get_recent_messages(3), keywords=task_keywords)
        except Exception as e:
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(f"更新记忆失败: {str(e)}", OutputType.WARNING)
    
    def _extract_task_keywords(self) -> List[str]:
        """提取任务相关关键词，子类可以重写"""
        return []
    
    @abc.abstractmethod
    def chat(self, user_input: str, reset: bool = False) -> str:
        """聊天接口，子类必须实现"""
        pass